/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package managedbean.SOP;

import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import merlion.common.entity.GlobalVariable;
import merlion.common.entity.Staff;
import merlion.common.session.stateless.GlobalVariableSessionBeanLocal;
import merlion.common.util.Consts;
import merlion.common.util.exception.NotExistException;
import merlion.crm.slcm.entity.Address;
import merlion.crm.slcm.entity.Customer;
import merlion.crm.slcm.entity.MemberDiscountGroup;
import merlion.crm.slcm.entity.OrderDiscountGroup;
import merlion.crm.slcm.session.SLCSessionBeanLocal;
import merlion.crm.sopm.entity.ItemLine;
import merlion.crm.sopm.entity.PurchaseOrder;
import merlion.crm.sopm.entity.SalesQuotation;
import merlion.crm.sopm.session.SOPSessionBeanLocal;
import merlion.mrp.ppm.entity.Product;
import merlion.scm.lcm.entity.DeliveryOrder;
import merlion.scm.lcm.session.LogisticControlSessionBeanLocal;
import org.primefaces.context.RequestContext;

/**
 *
 * @author Yuwei
 */
@ManagedBean(name = "poManagerBean")
@ViewScoped
public class PurchaseOrderManagerBean {

    public static final String PO = "PO";
    public static final String RESULT1 = "RESULT1";
    public static final String CUR = "CUR";
    public static final String PAYMODE = "PAYMODE";
    @EJB
    private SOPSessionBeanLocal sOPSessionBean;
    @EJB
    private SLCSessionBeanLocal sLCSessionBean;
    @EJB
    private LogisticControlSessionBeanLocal lcSessionBean;
    @EJB
    private GlobalVariableSessionBeanLocal gvSessionBean;
    private PurchaseOrder purchaseOrder;
    private SalesQuotation salesQuotation;
    private OrderDiscountGroup orderDiscountGroup;
    private OrderDiscountGroup sqOrderDiscountGroup;
    private Customer customer;
    private String poNumStr;
    private String customerIdStr;
    private String currency;
    private String paymentMode;
    private String comments;
    private Address shippingAddress;
    private Double memberDiscount;
    private Double orderDiscount;
    private Double subtotalSum;
    private Double itemSubtotal;
    private Double subtotal;
    private Double total;
    private Double taxRate;
    private Double tax;
    private Double taxDisplay;
    private String salesQuotationIdStr;
    private String sqCustomerId;
    private String result;
    private ItemLine newItemLine;
    private DeliveryOrder newDeliveryOrder;
    private DeliveryOrder newDeliveryOrder2;
    private DeliveryOrder selectedDeliveryOrder;
    private boolean updateMode;
    private Collection<Long> orderQtys = new ArrayList<Long>();
    private Collection<OrderDiscountGroup> orderDiscountGroups = new ArrayList<OrderDiscountGroup>();
    private Collection<Double> subtotals = new ArrayList<Double>();
    private String statusMessage;
    private static final SimpleDateFormat formatter = new SimpleDateFormat("MMMMM dd, yyyy");
    private Date date1;
    private Date date2;

    public PurchaseOrderManagerBean() {
        System.out.println("######################################PurchaseOrderManagerBean initialized!!!!");
        this.purchaseOrder = new PurchaseOrder();
        subtotalSum = 0.00;
        customer = new Customer();
        purchaseOrder.setCustomer(customer);


    }

    @PostConstruct
    public void init() {
        
        
        PurchaseOrder po = (PurchaseOrder) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("PO");
        if (po != null) {

            purchaseOrder = po;
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("PO");
        } else {
            purchaseOrder = new PurchaseOrder();
            purchaseOrder.setTaxRate(gvSessionBean.getGlobalVariableByKey(Consts.GLOBAL_TAX_RATE).getDoubleValue().doubleValue());
            purchaseOrder.setCurrency(null);
            purchaseOrder.setCustomerExecutive((Staff) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("app.user.name"));
        }

        if (!purchaseOrder.getPoNumber().equals("")) {

            //if edit
            if (purchaseOrder.getTotal() != (double) 0.0) {
                Collection<DeliveryOrder> list = purchaseOrder.getDeliveryOrders();
                Iterator iter = list.iterator();
                newDeliveryOrder = (DeliveryOrder) iter.next();
                if (iter.hasNext()) {
                    newDeliveryOrder2 = (DeliveryOrder) iter.next();
                }
                return;
            } else {
                setDeliveryOrder();
            }

        } else {
            // if create
            createNewItemLines();
            createNewDeliveryOrder();
            createNewDeliveryOrder2();
        }
    }

    public boolean displayItemLine(Long rowIndex) {

        Collection<ItemLine> collection = purchaseOrder.getItemLines();
        ArrayList<ItemLine> list = new ArrayList<ItemLine>();
        for (ItemLine il : collection) {
            list.add(il);
        }

        ItemLine il = (ItemLine) list.get(rowIndex.intValue());
        if (il.getQtyOrderedCase() == 0) {
            return false;
        }
        return true;
    }

    public Collection<Address> getCustomerAddress() {
        Customer c1 = null;
        try {
            c1 = sLCSessionBean.getCustomerById(purchaseOrder.getCustomer().getId());
            return c1.getShippingAddress();
        } catch (NotExistException ex) {
            System.out.println("Client does not exist: " + ex.getMessage());
        }
        return null;
    }

    public void setDeliveryOrder() {

        //if full shipment
        if (purchaseOrder.getFullShipment()) {


            Collection<ItemLine> itemLines = purchaseOrder.getItemLines();

            createNewDeliveryOrder();

            Collection<ItemLine> deliveryOrderItemLine = new ArrayList<ItemLine>();
            for (ItemLine il : itemLines) {
                ItemLine il1 = new ItemLine();
                il1.setMemberDiscount(il.getMemberDiscount());
                il1.setOrderDiscount(il.getOrderDiscount());
                il1.setProduct(il.getProduct());
                il1.setQtyAvailable(il.getQtyAvailable());
                il1.setQtyOrderedBar(il.getQtyOrderedBar());
                il1.setQtyOrderedCase(il.getQtyOrderedCase());
                il1.setSubTotal(il.getSubTotal());
                il1.setTimeCreated(il.getTimeCreated());
                il1.setTotal(il.getTotal());
//                il1.setWarehouse(il.getWarehouse());
                deliveryOrderItemLine.add(il1);
            }
            newDeliveryOrder.setItemLines(deliveryOrderItemLine);
            newDeliveryOrder.setPurchaseOrder(purchaseOrder);

            ArrayList<DeliveryOrder> dl = new ArrayList<DeliveryOrder>();
            dl.add(newDeliveryOrder);

            purchaseOrder.setDeliveryOrders(dl);

        } else { //if partial shipment

            Collection<ItemLine> itemLines = purchaseOrder.getItemLines();

            createNewDeliveryOrder();
            createNewDeliveryOrder2();

            Collection<ItemLine> deliveryOrderItemLine = new ArrayList<ItemLine>();
            Collection<ItemLine> deliveryOrderItemLine2 = new ArrayList<ItemLine>();
            for (ItemLine il : itemLines) {

                ItemLine il1 = new ItemLine();
                il1.setMemberDiscount(il.getMemberDiscount());
                il1.setOrderDiscount(il.getOrderDiscount());
                il1.setProduct(il.getProduct());
                il1.setQtyAvailable(il.getQtyAvailable());
                il1.setQtyOrderedBar(il.getQtyOrderedBar());
                il1.setQtyOrderedCase((long) il.getQtyOrderedCase() / (long) 2);
                il1.setSubTotal(il.getSubTotal());
                il1.setTimeCreated(il.getTimeCreated());
                il1.setTotal(il.getTotal());
//                il1.setWarehouse(il.getWarehouse());

                ItemLine il2 = new ItemLine();
                il2.setMemberDiscount(il.getMemberDiscount());
                il2.setOrderDiscount(il.getOrderDiscount());
                il2.setProduct(il.getProduct());
                il2.setQtyAvailable(il.getQtyAvailable());
                il2.setQtyOrderedBar(il.getQtyOrderedBar());
                il2.setQtyOrderedCase((long) il.getQtyOrderedCase() - (long) il1.getQtyOrderedCase());
                il2.setSubTotal(il.getSubTotal());
                il2.setTimeCreated(il.getTimeCreated());
                il2.setTotal(il.getTotal());
                //            il2.setWarehouse(il.getWarehouse());

                deliveryOrderItemLine.add(il1);
                deliveryOrderItemLine2.add(il2);
            }
            newDeliveryOrder.setItemLines(deliveryOrderItemLine);
            newDeliveryOrder2.setItemLines(deliveryOrderItemLine2);
            newDeliveryOrder.setPurchaseOrder(purchaseOrder);
            newDeliveryOrder2.setPurchaseOrder(purchaseOrder);

            ArrayList<DeliveryOrder> dl = new ArrayList<DeliveryOrder>();
            dl.add(newDeliveryOrder);
            dl.add(newDeliveryOrder2);
            purchaseOrder.setDeliveryOrders(dl);
        }

    }

    private void createNewItemLines() {

        Collection<ItemLine> itemLines = new ArrayList<ItemLine>();
        purchaseOrder.setItemLines(itemLines);

        //Add itemline for all products
        Collection<Product> products = sLCSessionBean.getAllProduct();
        for (Product pd : products) {
            ItemLine il = new ItemLine();
//            il.setWarehouse(null);
            il.setProduct(pd);
            itemLines.add(il);
        }
    }

    private void createNewDeliveryOrder() {
        newDeliveryOrder = new DeliveryOrder();
        newDeliveryOrder.setLeadTime(null);
        newDeliveryOrder.setUrgent(Boolean.FALSE);
        newDeliveryOrder.setItemLines(new ArrayList<ItemLine>());
        newDeliveryOrder.setInvoice(null);
        newDeliveryOrder.setPurchaseOrder(purchaseOrder);
        newDeliveryOrder.setSalesOrder(null);
        newDeliveryOrder.setSalesQuotation(null);
        newDeliveryOrder.setActive(false);

        //Add itemline for all products
        Collection<Product> products = sLCSessionBean.getAllProduct();
        for (Product pd : products) {
            ItemLine il = new ItemLine();
//            il.setWarehouse(null);
            il.setProduct(pd);
            newDeliveryOrder.getItemLines().add(il);
        }
    }

    private void createNewDeliveryOrder2() {
        newDeliveryOrder2 = new DeliveryOrder();
        newDeliveryOrder2.setLeadTime(null);
        newDeliveryOrder2.setUrgent(Boolean.FALSE);
        newDeliveryOrder2.setItemLines(new ArrayList<ItemLine>());
        newDeliveryOrder2.setInvoice(null);
        newDeliveryOrder2.setPurchaseOrder(purchaseOrder);
        newDeliveryOrder2.setSalesOrder(null);
        newDeliveryOrder2.setSalesQuotation(null);
        newDeliveryOrder2.setActive(false);

        //Add itemline for all products
        Collection<Product> products = sLCSessionBean.getAllProduct();
        for (Product pd : products) {
            ItemLine il = new ItemLine();
//            il.setWarehouse(null);
            il.setProduct(pd);
            newDeliveryOrder2.getItemLines().add(il);
        }
    }

    public void addDeliveryOrder() {
        //TODO: Validate newDeliveryOrder
        RequestContext context = RequestContext.getCurrentInstance();
        boolean valid1 = true;
        boolean valid2 = true;
        boolean valid3 = true;
        if (newDeliveryOrder.getShippingAddress().getAddressLine1().equals("")
                || newDeliveryOrder.getShippingAddress().getCity().equals("")
                || newDeliveryOrder.getShippingAddress().getZipCode().equals("") || newDeliveryOrder.getShippingAddress().getCountry().equals("")
                || newDeliveryOrder.getShippingAddress().getStateName().equals("")) {
            valid1 = false;
        }

        //Validation: One orderline should have at least one itemline
        int count = 0;
        for (ItemLine il : newDeliveryOrder.getItemLines()) {
            if (il.getQtyOrderedCase() == 0) {
                count++;
            }
        }
        if (count >= 4) {
            valid1 = false;
        }


        context.addCallbackParam("valid1", valid1);

        for (ItemLine il : newDeliveryOrder.getItemLines()) {
            if (purchaseOrder.getCustomer().getCategory().equals("DirectSale")) {
                if (il.getQtyOrderedCase() < 10 && il.getQtyOrderedCase() != 0) {
                    valid2 = false;
                }
            } else {//for whole sale customers
                if (il.getQtyOrderedCase() < 50 && il.getQtyOrderedCase() != 0) {
                    valid3 = false;
                }
            }
        }
        context.addCallbackParam("valid2", valid2);
        context.addCallbackParam("valid3", valid3);

        if (!valid1 || !valid2 || !valid3) {
            return;
        }

        //Add newDeliveryOrder to salesQuotation
        if (purchaseOrder.getFullShipment() == Boolean.TRUE && purchaseOrder.getDeliveryOrders().size() > 1) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "You can only have one orderline for full shipment", "You can only have one orderline for full shipment"));
            return;
        }
        //Add newDeliveryOrder to purchaseOrder
        newDeliveryOrder.setPurchaseOrder(this.purchaseOrder);
        purchaseOrder.addDeliveryOrder(newDeliveryOrder);

        //Reset newDeliveryOrder
        createNewDeliveryOrder();
    }

    public void updateDeliveryOrder() {
        //TODO: Validate selectedDeliveryOrder
        RequestContext context = RequestContext.getCurrentInstance();
        boolean valid1 = true;
        boolean valid2 = true;
        boolean valid3 = true;
        if (selectedDeliveryOrder.getShippingAddress().getAddressLine1().equals("")
                || selectedDeliveryOrder.getShippingAddress().getCity().equals("")
                || selectedDeliveryOrder.getShippingAddress().getZipCode().equals("") || selectedDeliveryOrder.getShippingAddress().getCountry().equals("")
                || selectedDeliveryOrder.getShippingAddress().getStateName().equals("")) {
            valid1 = false;
        }

        //Validation: One orderline should have at least one itemline
        int count = 0;
        for (ItemLine il : selectedDeliveryOrder.getItemLines()) {
            if (il.getQtyOrderedCase() == 0) {
                count++;
            }
        }
        if (count == 4) {
            valid1 = false;
        }


        context.addCallbackParam("valid1", valid1);

        for (ItemLine il : selectedDeliveryOrder.getItemLines()) {
            if (purchaseOrder.getCustomer().getCategory().equals("DirectSale")) {
                if (il.getQtyOrderedCase() < 10 && il.getQtyOrderedCase() != 0) {
                    valid2 = false;
                }
            } else {//for whole sale customers
                if (il.getQtyOrderedCase() < 50 && il.getQtyOrderedCase() != 0) {
                    valid3 = false;
                }
            }
        }
        context.addCallbackParam("valid2", valid2);
        context.addCallbackParam("valid3", valid3);

        if (!valid1 || !valid2 || !valid3) {
            return;
        }
        if (purchaseOrder.getFullShipment() == Boolean.TRUE && purchaseOrder.getDeliveryOrders().size() > 1) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "You can only have one orderline for full shipment", "You can only have one orderline for full shipment"));
            return;
        }
        //Set selectedDeliveryOrder leadTime
        for (DeliveryOrder ol : purchaseOrder.getDeliveryOrders()) {
            if (ol.equals(selectedDeliveryOrder)) {
                //Swap
                ol = selectedDeliveryOrder;
            }
        }
    }

    public void removeDeliveryOrder() {
        selectedDeliveryOrder.setPurchaseOrder(null);
        Collection<DeliveryOrder> ols = purchaseOrder.getDeliveryOrders();
        ols.remove(selectedDeliveryOrder);
    }

    public void reset() {
        createNewDeliveryOrder();
    }

    public Collection<Product> getAllProduct() {
        return sLCSessionBean.getAllProduct();
    }

    public String createPurchaseOrder() {

        SalesQuotation sq = purchaseOrder.getSalesQuotation();
        PurchaseOrder po = purchaseOrder;
        if(!validateAddress()){
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Please fill in the address information completely", ""));
            return null;
        }
        boolean valid = true;
        //Validate
        if (po.getFreightOnBoard() != sq.getFreightOnBoard()) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Corresponding Sales Quotation has different shipping terms for freight on board", ""));
            valid = false;
        }
        if (po.getFullShipment() != sq.getFullShipment()) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Corresponding Sales Quotation has different shipping terms for shipping details", ""));
            valid = false;
        }
        //check item line discount
        ArrayList<ItemLine> poItem = new ArrayList<ItemLine>(po.getItemLines());
        ArrayList<ItemLine> sqItem = new ArrayList<ItemLine>(sq.getItemLines());
        for (int i = 0; i < poItem.size(); i++) {
            System.out.println("PO Special discount: " + poItem.get(i).getSpecialDiscount());
            System.out.println("SQ Special discount: " + sqItem.get(i).getSpecialDiscount());
            if ((double) poItem.get(i).getSpecialDiscount() != (double) sqItem.get(i).getSpecialDiscount()) {
                valid = false;
            }
        }
        if (!valid) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Corresponding Sales Quotation order items has different special discount", ""));
        }
       
        // Check item quantity
        if (!purchaseOrder.getFullShipment()) {

            //Check total quantity
            long totalQuantity = (long) 0;
            long purchaseOrderQuantity = (long) 0;
            ArrayList<DeliveryOrder> dls = new ArrayList<DeliveryOrder>();
            dls.add(newDeliveryOrder);
            dls.add(newDeliveryOrder2);
            for (DeliveryOrder dl : dls) {
                Collection<ItemLine> ils = dl.getItemLines();
                for (ItemLine il : ils) {
                    totalQuantity += il.getQtyOrderedCase();
                }
            }
            for (ItemLine il : purchaseOrder.getItemLines()) {
                purchaseOrderQuantity += il.getQtyOrderedCase();
            }
            if (totalQuantity != purchaseOrderQuantity) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Delivery Order quantity does not sum up to total order quantity", ""));
                valid = false;
            }

            //Check minimum quantity
            for (ItemLine il : newDeliveryOrder.getItemLines()) {
                if (purchaseOrder.getCustomer().getCategory().equals("DirectSale")) {
                    if (il.getQtyOrderedCase() < 5 && il.getQtyOrderedCase() != 0) {
                        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Delivery Order 1: Minimum delivery order for each product is 5", ""));
                        valid = false;
                    }
                } else {//for whole sale customers
                    if (il.getQtyOrderedCase() < 5 && il.getQtyOrderedCase() != 0) {
                        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Delivery Order 1: Minimum delivery order for each product is 5", ""));
                        valid = false;
                    }
                }
            }
            for (ItemLine il : newDeliveryOrder2.getItemLines()) {
                if (purchaseOrder.getCustomer().getCategory().equals("DirectSale")) {
                    if (il.getQtyOrderedCase() < 5 && il.getQtyOrderedCase() != 0) {
                        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Delivery Order 2: Minimum delivery order for each product is 5", ""));
                        valid = false;
                    }
                } else {//for whole sale customers
                    if (il.getQtyOrderedCase() < 5 && il.getQtyOrderedCase() != 0) {
                        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Delivery Order 2: Minimum delivery order for each product is 5", ""));
                        valid = false;
                    }
                }
            }
        }

        if (!valid) {
            return null;
        } else {
            // Continue to validate delivery order
            ArrayList<DeliveryOrder> poList = new ArrayList<DeliveryOrder>(po.getDeliveryOrders());
            ArrayList<DeliveryOrder> sqList = new ArrayList<DeliveryOrder>(sq.getDeliveryOrders());

            for (int i = 0; i < poList.size(); i++) {

                DeliveryOrder podo = poList.get(i);
                boolean found = false;
                int j = 0;
                for (; j < sqList.size(); j++) {

                    DeliveryOrder sqdo = sqList.get(j);
                    ArrayList<ItemLine> poil = new ArrayList<ItemLine>(podo.getItemLines());
                    ArrayList<ItemLine> sqil = new ArrayList<ItemLine>(sqdo.getItemLines());
                    boolean match = true;
                    for (int k = 0; k < poil.size(); k++) {
                        System.out.println("poil: " + poil.get(k).getQtyOrderedCase() + j);
                        System.out.println("sqil: " + sqil.get(k).getQtyOrderedCase() + j);
                        if ((double) poil.get(k).getOrderDiscount() != (double) sqil.get(k).getOrderDiscount()) {
                            match = false;
                        }
                        if ((double) poil.get(k).getSpecialDiscount() != (double) sqil.get(k).getSpecialDiscount()) {
                            match = false;
                        }
                    }
                    if (match) {
                        found = true;
                        break;
                    }
                }
                if (found) {
                    poList.remove(i);
                    sqList.remove(j);
                    i = -1;
                }
            }

            if (!poList.isEmpty()) {
                FacesContext.getCurrentInstance().addMessage(null,
                        new FacesMessage(FacesMessage.SEVERITY_ERROR, "Corresponding Sales Quotation has different delivery order item quantities", ""));
                valid = false;
            }
        }
        if (!valid) {
            return null;
        }

        calculate();

        for (DeliveryOrder del : purchaseOrder.getDeliveryOrders()) {
            del.setPurchaseOrder(purchaseOrder);
        }

        // If no comments, write no comments
        if (purchaseOrder.getComments().equals("")) {
            purchaseOrder.setComments("No additional comments from customer");
        }

        
        

        //Calculate Delivery Order totals for Partial Shipping

        ArrayList<DeliveryOrder> finalOrders = new ArrayList<DeliveryOrder>();
        ArrayList<DeliveryOrder> dos = new ArrayList<DeliveryOrder>(purchaseOrder.getDeliveryOrders());
        long eightHours = (long) (8 * 60 * 60 * 1000);
        if (date1 != null) {
            dos.get(0).setLeadTimeTS(new Timestamp(date1.getTime() + eightHours));
        }
        else {
            dos.get(0).setLeadTimeTS(null);
        }
        if (date2 != null && dos.size() > 1) {
            dos.get(1).setLeadTimeTS(new Timestamp(date2.getTime() + eightHours));
        }
        if (date2 == null && dos.size() > 1) {
            dos.get(1).setLeadTimeTS(null);
        }
        for (int k = 0; k < dos.size(); k++) {
            DeliveryOrder deliveryOrder = dos.get(k);
            DeliveryOrder finalOrder = new DeliveryOrder();
            finalOrder.setShippingAddress(deliveryOrder.getShippingAddress());
            finalOrder.setLeadTimeTS(deliveryOrder.getLeadTimeTS());

            double deliverySubtotal = (double) 0;
            double deliveryTotal = (double) 0;
            double sdAmount = (double) 0;
            double mdAmount = (double) 0;
            double odAmount = (double) 0;
            for (int j = 0; j < deliveryOrder.getItemLines().size(); j++) {
                ArrayList<ItemLine> items = new ArrayList<ItemLine>(deliveryOrder.getItemLines());
                ArrayList<ItemLine> totalItemLines = new ArrayList<ItemLine>(purchaseOrder.getItemLines());
                ItemLine item = items.get(j);
                ItemLine finalItem = new ItemLine();

                finalItem.setQtyOrderedCase(item.getQtyOrderedCase());
                if (finalItem.getProduct().getProductType().contains("Classic")) {
                    finalItem.setQtyOrderedBar(finalItem.getQtyOrderedCase() * 240);
                } else {
                    finalItem.setQtyOrderedBar(finalItem.getQtyOrderedCase() * 200);
                }
                finalItem.setProduct(totalItemLines.get(j).getProduct());
                finalItem.setMemberDiscount(totalItemLines.get(j).getMemberDiscount());
                finalItem.setOrderDiscount(totalItemLines.get(j).getOrderDiscount());
                finalItem.setSpecialDiscount(totalItemLines.get(j).getSpecialDiscount());
                finalItem.setUnitPriceSGD(totalItemLines.get(j).getUnitPriceSGD());
                finalItem.setUnitPriceUSD(totalItemLines.get(j).getUnitPriceUSD());
//                finalItem.setWarehouse(null);

                double quantityBar = finalItem.getQtyOrderedBar();
                double od = finalItem.getOrderDiscount();
                double md = finalItem.getMemberDiscount();
                double sd = finalItem.getSpecialDiscount();
                double unitPrice;
                if (purchaseOrder.getCurrency() == Boolean.TRUE) {
                    //SGD
                    if (finalItem.getProduct().getProductType().contains("Classic")) {
                        unitPrice = finalItem.getUnitPriceSGD() / 240;
                    } else {
                        unitPrice = finalItem.getUnitPriceSGD() / 200;
                    }
                } else {
                    //USD
                    if (finalItem.getProduct().getProductType().contains("Classic")) {
                        unitPrice = finalItem.getUnitPriceUSD() / 240;
                    } else {
                        unitPrice = finalItem.getUnitPriceUSD() / 200;
                    }

                }
                finalItem.setSubTotal((double) quantityBar * (double) unitPrice * ((double) 1.0 - (double) od) * ((double) 1 - (double) md) * ((double) 1 - (double) sd));
                deliveryTotal = deliveryTotal + (double) quantityBar * (double) unitPrice * ((double) 1.0 - (double) od) * ((double) 1 - (double) md) * ((double) 1 - (double) sd);
                deliverySubtotal = deliverySubtotal + (double) quantityBar * (double) unitPrice;
                odAmount = odAmount + (double) quantityBar * (double) unitPrice * (double) od;
                mdAmount = mdAmount + (double) quantityBar * (double) unitPrice * ((double) 1.0 - (double) od) * ((double) md);
                sdAmount = sdAmount + (double) quantityBar * (double) unitPrice * ((double) 1.0 - (double) od) * ((double) 1 - (double) md) * (double) sd;

                finalOrder.getItemLines().add(finalItem);

            }

            finalOrder.setSubtotal(deliverySubtotal);
            finalOrder.setSpecialDiscount(sdAmount);
            finalOrder.setMemberDiscount(mdAmount);
            finalOrder.setOrderDiscount(odAmount);
            GlobalVariable taxGV = gvSessionBean.getGlobalVariableByKey(Consts.GLOBAL_TAX_RATE);
            finalOrder.setTax(taxGV.getDoubleValue().doubleValue() * (deliverySubtotal - sdAmount - odAmount - mdAmount));
            finalOrder.setTotal(deliverySubtotal + finalOrder.getTax() - sdAmount - odAmount - mdAmount);
            finalOrder.setSalesOrder(null);
            finalOrder.setSalesQuotation(null);
            finalOrder.setPurchaseOrder(purchaseOrder);
            finalOrder.setInvoice(null);
            finalOrders.add(finalOrder);
        }
        purchaseOrder.setDeliveryOrders(finalOrders);
        try {
            Customer c = sLCSessionBean.getCustomerByClientId(sq.getClient().getClientId());
            purchaseOrder.setCustomer(c);
            c.getPurchaseOrders().add(purchaseOrder);
        } catch (NotExistException ex) {
            Logger.getLogger(PurchaseOrderManagerBean.class.getName()).log(Level.SEVERE, null, ex);
        }

        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(PO, purchaseOrder);
        return "createPurchaseOrderConfirm?faces-redirect=true";
    }

    public String recalculateSubtotal() {
        try {
            customer = sLCSessionBean.getCustomerByClientId(purchaseOrder.getCustomer().getClientId());
            purchaseOrder.setCustomer(customer);
        } catch (NotExistException ex) {
            return ex.getMessage();
        }
        //TO DO: match sales quotation with purchase order

        setCurrency();
        setPaymentMode();
        calculate();
        return "viewPurchaseOrderEditConfirm";
    }

    private void setCurrency() {
        //Set Currency
        if (currency.equals("SGD")) {
            purchaseOrder.setCurrency(Boolean.TRUE);
        } else {//us dollars
            purchaseOrder.setCurrency(Boolean.FALSE);
        }
    }

    private void setPaymentMode() {
        //Set Payment mode
        if (paymentMode.equals("CIA")) {
            purchaseOrder.setPaymentMode(Boolean.TRUE);
        } else {//pay by credit
            purchaseOrder.setPaymentMode(Boolean.FALSE);
        }
    }

    private void calculate() {
        //Get Member Discount
        MemberDiscountGroup memberDiscountGroup = sLCSessionBean.getCustomerMemberDiscountGroup(purchaseOrder.getCustomer());
        memberDiscount = memberDiscountGroup.getMemberDiscount();
        double md = memberDiscount;
        double odAmount = (double) 0;
        double mdAmount = (double) 0;
        double sdAmount = (double) 0;
        double originalPrice = (double) 0;
        //Get Order Discount
        ArrayList<ItemLine> totalItemLines = new ArrayList<ItemLine>(purchaseOrder.getItemLines());
        for (int i = 0; i < totalItemLines.size(); i++) {
            ItemLine il = totalItemLines.get(i);
            double quantityBar;
            if (il.getProduct().getProductType().contains("Classic")) {
                quantityBar = (double) il.getQtyOrderedCase()*240;
            } else {
                quantityBar = (double) il.getQtyOrderedCase()*200;
            }
            il.setQtyOrderedBar(new Double(quantityBar).longValue());
            orderDiscountGroup = sLCSessionBean.getOrderDiscountGroup(il);
            il.setOrderDiscount(orderDiscountGroup.getOrderDiscount());
            il.setMemberDiscount(memberDiscount);

            //Calculate Subtotal
            if (purchaseOrder.getCustomer().getCategory().equals("DirectSale")) {
                if (il.getProduct().getProductType().contains("Classic")){
                il.setUnitPriceSGD(roundFourDecimals(il.getProduct().getDsUnitPrice()*240));
                il.setUnitPriceUSD(roundFourDecimals(il.getProduct().getDsUnitPrice() / 1.2*240));}
                else {
                il.setUnitPriceSGD(roundFourDecimals(il.getProduct().getDsUnitPrice()*200));
                il.setUnitPriceUSD(roundFourDecimals(il.getProduct().getDsUnitPrice() / 1.2*200));
            }
            } else { //WholeSale Customers
                if (il.getProduct().getProductType().contains("Classic")) {
                    il.setUnitPriceSGD(roundFourDecimals(il.getProduct().getWsUnitPrice() * 240));
                    il.setUnitPriceUSD(roundFourDecimals(il.getProduct().getWsUnitPrice() / 1.2 * 240));
                } else {
                    il.setUnitPriceSGD(roundFourDecimals(il.getProduct().getWsUnitPrice() * 200));
                    il.setUnitPriceUSD(roundFourDecimals(il.getProduct().getWsUnitPrice() / 1.2 * 200));
                }
            }
             double unitPrice;
            if (purchaseOrder.getCurrency() == Boolean.TRUE) {
                //SGD
                if (il.getProduct().getProductType().contains("Classic")) {
                    unitPrice = il.getUnitPriceSGD() / 240;
                } else {
                    unitPrice = il.getUnitPriceSGD() / 200;
                }
            } else {
                //USD
                if (il.getProduct().getProductType().contains("Classic")) {
                    unitPrice = il.getUnitPriceUSD() / 240;
                } else {
                    unitPrice = il.getUnitPriceUSD() / 200;
                }

            }
            double od = (double) il.getOrderDiscount();
            double sd = (double) il.getSpecialDiscount();
            itemSubtotal = (double) quantityBar * (double) unitPrice * ((double) 1.0 - (double) od) * ((double) 1 - (double) md) * ((double) 1 - (double) sd);
            originalPrice = originalPrice + (double) quantityBar * (double) unitPrice;
            odAmount = odAmount + (double) quantityBar * (double) unitPrice * (double) od;
            mdAmount = mdAmount + (double) quantityBar * (double) unitPrice * ((double) 1.0 - (double) od) * ((double) md);
            sdAmount = sdAmount + (double) quantityBar * (double) unitPrice * ((double) 1.0 - (double) od) * ((double) 1 - (double) md) * (double) sd;
            //Rounding
            itemSubtotal = roundFourDecimals(itemSubtotal);
            il.setSubTotal(itemSubtotal);
            subtotals.add(itemSubtotal);
            subtotalSum = subtotalSum + itemSubtotal;
            totalItemLines.set(i, il);
        }
        purchaseOrder.setSubtotal(originalPrice);
        purchaseOrder.setMemberDiscount(mdAmount);
        purchaseOrder.setOrderDiscount(odAmount);
        purchaseOrder.setSpecialDiscount(sdAmount);
        purchaseOrder.setTax(subtotalSum * purchaseOrder.getTaxRate());
        purchaseOrder.setTotal(subtotalSum + purchaseOrder.getTax());
    }

    public String confirmPurchaseOrder() {
        //persist purchase order
        PurchaseOrder po = sOPSessionBean.savePurchaseOrder(purchaseOrder);
        if (po != null) {
            System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ purchase order " + po.getPoNumber() + " saved successfully");
            result = "Purchase Order of ID " + po.getId() + " , Purchase Order Number " + po.getPoNumber() + " saved successfully.";
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(RESULT1, result);
            return "viewPurchaseOrderStatus";
        } else {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Purchase Order didn't saved successfully.", "Purchase Order didn't saved successfully."));
            return null;
        }
    }

    private double roundTwoDecimals(double d) {
        DecimalFormat twoDForm = new DecimalFormat("#.##");
        return Double.valueOf(twoDForm.format(d));
    }

    private double roundFourDecimals(double d) {
        DecimalFormat fourDForm = new DecimalFormat("#.####");
        return Double.valueOf(fourDForm.format(d));
    }

    public String cancelPurchaseOrder() {
        System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Cancel Purchase Order called............");
        FacesContext.getCurrentInstance().addMessage(null,
                new FacesMessage(FacesMessage.SEVERITY_ERROR, "Purchase Order creation cancelled", "Purchase Order creation cancelled"));
        result = "Purchase Order cancelled and has not been saved.";
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(RESULT1, result);
        return "viewPurchaseOrderStatus?faces-redirect=true";
    }

    public String populatePurchaseOrder() {
        try {
            purchaseOrder = sOPSessionBean.getPurchaseOrderById(purchaseOrder.getPoNumber());
        } catch (NotExistException e) {
            //TO DO: Handle exceptions
        }
        customer = purchaseOrder.getCustomer();
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(PO, purchaseOrder);
        return "viewPurchaseOrderDisplay?faces-redirect=true";
    }

//    public String populateToEditPurchaseOrder() {
//        try {
//            purchaseOrder = sOPSessionBean.getPurchaseOrderById(poNumStr);
//        } catch (NotExistException e) {
//            //TO DO: Handle exceptions
//        }
//        customer = purchaseOrder.getCustomer();
//        boolean currencyBoolean = purchaseOrder.getCurrency();
//        if (currencyBoolean == Boolean.TRUE) {
//            currency = "SGD";
//        } else {
//            currency = "USD";
//        }
//        boolean paymentModeBoolean = purchaseOrder.getPaymentMode();
//        if (paymentModeBoolean == Boolean.TRUE) {
//            paymentMode = "CIA";
//        } else {
//            paymentMode = "PBC";
//        }
//        return "editPurchaseOrder";
//    }
    public String updatePurchaseOrder() {
        if (purchaseOrder.getSalesOrder() != null) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Purchase Order cannot be edited after associated sales order has been created", "Purchase Order cannot be edited after assotiated sales order has been created"));
            return null;
        }
        customer = purchaseOrder.getCustomer();

        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(PO, purchaseOrder);
        return "viewPurchaseOrderEdit?faces-redirect=true";
    }

    public String closePurchaseOrder() {
        result = "Purchase Order " + purchaseOrder.getPoNumber() + " closed.";
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(RESULT1, result);
        return "viewPurchaseOrderStatus?faces-redirect=true";
    }

    public String cancelEditPO() {
        result = "Purchase Order " + purchaseOrder.getPoNumber() + " cancel edit.";
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(RESULT1, result);
        return "viewPurchaseOrderStatus?faces-redirect=true";
    }

    private String convertToDateFormat(Timestamp timeStamp) {
        return formatter.format((java.util.Date) timeStamp);
    }

    public String next() {

        //Validation: match sales quotation with purchase order
        try {
            salesQuotation = sOPSessionBean.getSalesQuotationById(purchaseOrder.getSalesQuotation().getSqNumber());

            //check whether the same customer
            if (!purchaseOrder.getCustomer().getClientId().equals(salesQuotation.getClient().getClientId())) {
                FacesContext.getCurrentInstance().addMessage(null,
                        new FacesMessage(FacesMessage.SEVERITY_ERROR, "Corresponding Sales Quotation has different customer", "Corresponding Sales Quotation has different customer."));
                return null;
            }

            //Check PO number: cannot duplicate
            Boolean newPo = sOPSessionBean.checkDuplicatePoNumber(purchaseOrder.getPoNumber());
            if(!newPo){
                FacesContext.getCurrentInstance().addMessage(null,
                        new FacesMessage(FacesMessage.SEVERITY_ERROR, "PO Number has been used by another purchase order. PO number must be unique.", "PO number already existed."));
                return null;
            }

            //check valid period
            if (purchaseOrder.getPurchaseOrderDate().after(salesQuotation.getValidityDate())) {
                FacesContext.getCurrentInstance().addMessage(null,
                        new FacesMessage(FacesMessage.SEVERITY_ERROR, "Corresponding Sales Quotation has expired.", "Corresponding Sales Quotation has expired."));
                return null;
            }
            //check currency
            if (purchaseOrder.getCurrency() != salesQuotation.getCurrency()) {
                FacesContext.getCurrentInstance().addMessage(null,
                        new FacesMessage(FacesMessage.SEVERITY_ERROR, "Corresponding Sales Quotation has different currency", ""));
                return null;
            }


//        //Copy indicativeLeadTime from sales quotation's deliveryorder to purchase order's delivery order
//        List<DeliveryOrder> sqDos = (List<DeliveryOrder>) salesQuotation.getDeliveryOrders();
//        List<DeliveryOrder> poDos = (List<DeliveryOrder>) purchaseOrder.getDeliveryOrders();
//        for(int i = 0; i < sqDos.size(); i++){
//            for(int j = 0; j < poDos.size(); j++){
//                
//            }
//        }


            purchaseOrder.setSalesQuotation(salesQuotation);


            //----------------------------------------------------------------------
            //                          Calculate ItemLines
            //----------------------------------------------------------------------
            if (purchaseOrder.getCustomer() instanceof Customer) {
                try {
                    Customer c1 = sLCSessionBean.getCustomerByClientId(salesQuotation.getClient().getClientId());

                    //Get Member Discount
                    MemberDiscountGroup memberDiscountGroup = sLCSessionBean.getCustomerMemberDiscountGroup(c1);
                    memberDiscount = memberDiscountGroup.getMemberDiscount();
                } catch (Exception e) {
                    System.out.println("Exception: " + e.getMessage());
                }
            } else {
                memberDiscount = 0.0;
            }

            double md = memberDiscount;
            double odAmount = (double) 0;
            double mdAmount = (double) 0;
            double sdAmount = (double) 0;
            double originalPrice = (double) 0;
            //Get Order Discount
            ArrayList<ItemLine> totalItemLines = new ArrayList<ItemLine>(purchaseOrder.getItemLines());
            for (int i = 0; i < totalItemLines.size(); i++) {
                ItemLine il = totalItemLines.get(i);
                double quantityBar;
                if (il.getProduct().getProductType().contains("Classic")) {
                    quantityBar = (double) il.getQtyOrderedCase() * 240;
                } else {
                    quantityBar = (double) il.getQtyOrderedCase() * 200;
                }
                il.setQtyOrderedBar(new Double(quantityBar).longValue());
                orderDiscountGroup = sLCSessionBean.getOrderDiscountGroup(il);
                il.setOrderDiscount(orderDiscountGroup.getOrderDiscount());
                il.setMemberDiscount(memberDiscount);

                //Calculate Subtotal
                if (purchaseOrder.getCustomer().getCategory().equals("DirectSale")) {
                    if (il.getProduct().getProductType().contains("Classic")) {
                        il.setUnitPriceSGD(roundFourDecimals(il.getProduct().getDsUnitPrice() * 240));
                        il.setUnitPriceUSD(roundFourDecimals(il.getProduct().getDsUnitPrice() / 1.2 * 240));
                    } else {
                        il.setUnitPriceSGD(roundFourDecimals(il.getProduct().getDsUnitPrice() * 200));
                        il.setUnitPriceUSD(roundFourDecimals(il.getProduct().getDsUnitPrice() / 1.2 * 200));
                    }
                } else { //WholeSale clients
                    if (il.getProduct().getProductType().contains("Classic")) {
                        il.setUnitPriceSGD(roundFourDecimals(il.getProduct().getWsUnitPrice() * 240));
                        il.setUnitPriceUSD(roundFourDecimals(il.getProduct().getWsUnitPrice() / 1.2 * 240));
                    } else {
                        il.setUnitPriceSGD(roundFourDecimals(il.getProduct().getWsUnitPrice() * 200));
                        il.setUnitPriceUSD(roundFourDecimals(il.getProduct().getWsUnitPrice() / 1.2 * 200));
                    }
                }
          
                double unitPrice;
                if (purchaseOrder.getCurrency() == Boolean.TRUE) {
                    //SGD
                    if (il.getProduct().getProductType().contains("Classic")) {
                        unitPrice = il.getUnitPriceSGD() / 240;
                    } else {
                        unitPrice = il.getUnitPriceSGD() / 200;
                    }
                } else {
                    //USD
                    if (il.getProduct().getProductType().contains("Classic")) {
                        unitPrice = il.getUnitPriceUSD() / 240;
                    } else {
                        unitPrice = il.getUnitPriceUSD() / 200;
                    }

                }
                double od = (double) il.getOrderDiscount();
                double sd = (double) il.getSpecialDiscount();
                itemSubtotal = (double) quantityBar * (double) unitPrice * ((double) 1.0 - (double) od) * ((double) 1 - (double) md) * ((double) 1 - (double) sd);
                originalPrice = originalPrice + (double) quantityBar * (double) unitPrice;
                odAmount = odAmount + (double) quantityBar * (double) unitPrice * (double) od;
                mdAmount = mdAmount + (double) quantityBar * (double) unitPrice * ((double) 1.0 - (double) od) * ((double) md);
                sdAmount = sdAmount + (double) quantityBar * (double) unitPrice * ((double) 1.0 - (double) od) * ((double) 1 - (double) md) * (double) sd;
                //Rounding
                itemSubtotal = roundFourDecimals(itemSubtotal);
                il.setSubTotal(itemSubtotal);
                subtotals.add(itemSubtotal);
                subtotalSum = subtotalSum + itemSubtotal;
                totalItemLines.set(i, il);
            }

            //check total order items
            boolean sameItems = true;
            ArrayList<ItemLine> poList = new ArrayList<ItemLine>(purchaseOrder.getItemLines());
            ArrayList<ItemLine> sqList = new ArrayList<ItemLine>(salesQuotation.getItemLines());
            for (int i = 0; i < poList.size(); i++) {
                for (int j = 0; j < sqList.size(); j++) {
                    if (poList.get(i).getProduct().getProductType().equals(sqList.get(j).getProduct().getProductType())) {
                        if ((double) poList.get(i).getOrderDiscount() != (double) sqList.get(j).getOrderDiscount()) {
                            System.out.println("$#$#%$#%$#%%$%$#%$#%$#% po discount: " + poList.get(i).getOrderDiscount());
                            System.out.println("$#$#%$#%$#%%$%$#%$#%$#% sq discount: " + sqList.get(j).getOrderDiscount());
                            sameItems = false;
                            break;
                        }
                    }
                }
            }
            if (!sameItems) {
                FacesContext.getCurrentInstance().addMessage(null,
                        new FacesMessage(FacesMessage.SEVERITY_ERROR, "Purchase Order is invalid: discount tier different from corresponding sales quotation.", "Purchase Order is invalid: discount tier different from corresponding sales quotation."));
                return null;
            }
        } catch (NotExistException ex) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Cannot find corresponding sales quotation", "Cannot find corresponding sales quotation."));
            return null;
        }



        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("PO", purchaseOrder);
        return "createPurchaseOrderNext?faces-redirect=true";
    }

    ////////////////////////GETTER AND SETTOR///////////////////////////
    public Address getShippingAddress() {
        return shippingAddress;
    }

    public void setShippingAddress(Address shippingAddress) {
        this.shippingAddress = shippingAddress;
    }

    public String getStatusMessage() {
        return statusMessage;
    }

    public void setStatusMessage(String statusMessage) {
        this.statusMessage = statusMessage;
    }

    public Collection<OrderDiscountGroup> getOrderDiscountGroups() {
        return orderDiscountGroups;
    }

    public void setOrderDiscountGroups(Collection<OrderDiscountGroup> orderDiscountGroups) {
        this.orderDiscountGroups = orderDiscountGroups;
    }

    public Collection<Long> getOrderQtys() {
        return orderQtys;
    }

    public void setOrderQtys(Collection<Long> orderQtys) {
        this.orderQtys = orderQtys;
    }

    public Collection<Double> getSubtotals() {
        return subtotals;
    }

    public void setSubtotals(Collection<Double> subtotals) {
        this.subtotals = subtotals;
    }

    public PurchaseOrder getPurchaseOrder() {
        PurchaseOrder po = (PurchaseOrder) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(PO);
        if (po != null) {
            purchaseOrder = po;
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(PO);
        }
        return purchaseOrder;
    }

    public void setPurchaseOrder(PurchaseOrder purchaseOrder) {
        this.purchaseOrder = purchaseOrder;
    }

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    public String getComments() {
        return comments;
    }

    public void setComments(String comments) {
        this.comments = comments;
    }

    public String getCurrency() {
        String cur = (String) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(CUR);
        if (cur != null) {
            currency = cur;
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(CUR);
        }
        return currency;
    }

    public void setCurrency(String currency) {
        this.currency = currency;
    }

    public String getCustomerIdStr() {
        return customerIdStr;
    }

    public void setCustomerIdStr(String customerIdStr) {
        this.customerIdStr = customerIdStr;
    }

    public Double getMemberDiscount() {
        return memberDiscount;
    }

    public void setMemberDiscount(Double memberDiscount) {
        this.memberDiscount = memberDiscount;
    }

    public Double getOrderDiscount() {
        return orderDiscount;
    }

    public void setOrderDiscount(Double orderDiscount) {
        this.orderDiscount = orderDiscount;
    }

    public SLCSessionBeanLocal getsLCSessionBean() {
        return sLCSessionBean;
    }

    public void setsLCSessionBean(SLCSessionBeanLocal sLCSessionBean) {
        this.sLCSessionBean = sLCSessionBean;
    }

    public SOPSessionBeanLocal getsOPSessionBean() {
        return sOPSessionBean;
    }

    public void setsOPSessionBean(SOPSessionBeanLocal sOPSessionBean) {
        this.sOPSessionBean = sOPSessionBean;
    }

//    public ItemLine getIl() {
//        return il;
//    }
//
//    public void setIl(ItemLine il) {
//        this.il = il;
//    }
    public Double getItemSubtotal() {
        return itemSubtotal;
    }

    public void setItemSubtotal(Double itemSubtotal) {
        this.itemSubtotal = itemSubtotal;
    }

    public OrderDiscountGroup getOrderDiscountGroup() {
        return orderDiscountGroup;
    }

    public void setOrderDiscountGroup(OrderDiscountGroup orderDiscountGroup) {
        this.orderDiscountGroup = orderDiscountGroup;
    }

    public OrderDiscountGroup getSqOrderDiscountGroup() {
        return sqOrderDiscountGroup;
    }

    public void setSqOrderDiscountGroup(OrderDiscountGroup sqOrderDiscountGroup) {
        this.sqOrderDiscountGroup = sqOrderDiscountGroup;
    }

    public Double getSubtotalSum() {
        return subtotalSum;
    }

    public void setSubtotalSum(Double subtotalSum) {
        this.subtotalSum = subtotalSum;
    }

    public String getPaymentMode() {
        String paymode = (String) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(PAYMODE);
        if (paymode != null) {
            paymentMode = paymode;
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(PAYMODE);
        }
        return paymentMode;
    }

    public void setPaymentMode(String paymentMode) {
        this.paymentMode = paymentMode;
    }

    public Double getTax() {
        return tax;
    }

    public void setTax(Double tax) {
        this.tax = tax;
    }

    public Double getTaxRate() {
        return taxRate;
    }

    public void setTaxRate(Double taxRate) {
        this.taxRate = taxRate;
    }

    public Double getTotal() {
        return total;
    }

    public void setTotal(Double total) {
        this.total = total;
    }

    public String getPoNumStr() {
        return poNumStr;
    }

    public void setPoNumStr(String poNumStr) {
        this.poNumStr = poNumStr;
    }

    public String getSalesQuotationIdStr() {
        return salesQuotationIdStr;
    }

    public void setSalesQuotationIdStr(String salesQuotationIdStr) {
        this.salesQuotationIdStr = salesQuotationIdStr;
    }

    public SalesQuotation getSalesQuotation() {
        return salesQuotation;
    }

    public void setSalesQuotation(SalesQuotation salesQuotation) {
        this.salesQuotation = salesQuotation;
    }

    public String getSqCustomerId() {
        return sqCustomerId;
    }

    public void setSqCustomerId(String sqCustomerId) {
        this.sqCustomerId = sqCustomerId;
    }

    public String getResult() {
        String r = (String) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(RESULT1);
        if (r != null) {
            result = r;
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(RESULT1);
        }
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }

    public ItemLine getNewItemLine() {
        return newItemLine;
    }

    public void setNewItemLine(ItemLine newItemLine) {
        this.newItemLine = newItemLine;
    }

    public DeliveryOrder getNewDeliveryOrder() {
        return newDeliveryOrder;
    }

    public void setNewDeliveryOrder(DeliveryOrder newDeliveryOrder) {
        this.newDeliveryOrder = newDeliveryOrder;
    }

    public DeliveryOrder getSelectedDeliveryOrder() {
        return selectedDeliveryOrder;
    }

    public void setSelectedDeliveryOrder(DeliveryOrder selectedDeliveryOrder) {
        this.selectedDeliveryOrder = selectedDeliveryOrder;
    }

    public Double getSubtotal() {
        return subtotal;
    }

    public void setSubtotal(Double subtotal) {
        this.subtotal = subtotal;
    }

    public boolean isUpdateMode() {
        return updateMode;
    }

    public void setUpdateMode(boolean updateMode) {
        this.updateMode = updateMode;
    }

    public DeliveryOrder getNewDeliveryOrder2() {
        return newDeliveryOrder2;
    }

    public void setNewDeliveryOrder2(DeliveryOrder newDeliveryOrder2) {
        this.newDeliveryOrder2 = newDeliveryOrder2;
    }

    public Double getTaxDisplay() {
        return taxDisplay;
    }

    public void setTaxDisplay(Double taxDisplay) {
        this.taxDisplay = taxDisplay;
    }

    public Date getDate1() {
        return date1;
    }

    public void setDate1(Date date1) {
        this.date1 = date1;
    }

    public Date getDate2() {
        return date2;
    }

    public void setDate2(Date date2) {
        this.date2 = date2;
    }
    
     private boolean validateAddress(){
        boolean valid = true;
        // Address Line 1: Alphanumeric, Required
         if (purchaseOrder.getDeliveryOrders().size() == 1) {
             
             if (newDeliveryOrder.getShippingAddress() == null) {
                 FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address ", "cannot be empty."));
                 valid = false;
             }
             else {
             if (!isNotEmpty(newDeliveryOrder.getShippingAddress().getAddressLine1())) {
                 FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address Line 1", "cannot be empty."));
                 valid = false;
             }
             if (!isAlphanumeric(newDeliveryOrder.getShippingAddress().getAddressLine1())) {
                 FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address Line 1", "can only contain alphanumeric characters."));
                 valid = false;
             }

             // Zipcode: Numeric, Required
             if (!isNotEmpty(newDeliveryOrder.getShippingAddress().getZipCode())) {
                 FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address Zip Code", "cannot be empty."));
                 valid = false;
             }
             if (!isNumeric(newDeliveryOrder.getShippingAddress().getZipCode())) {
                 FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address Zip Code", "can only contain numeric characters."));
                 valid = false;
             }

             // City: Alphabetic, Required
             if (!isNotEmpty(newDeliveryOrder.getShippingAddress().getCity())) {
                 FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address City", "cannot be empty."));
                 valid = false;
             }
             if (!isAlphabetic(newDeliveryOrder.getShippingAddress().getCity())) {
                 FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address City", "can only contain alphabetical characters."));
                 valid = false;
             }

             // State: Alphabetic, Required
             if (!isNotEmpty(newDeliveryOrder.getShippingAddress().getStateName())) {
                 FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address State", "cannot be empty."));
                 valid = false;
             }
             if (!isAlphabetic(newDeliveryOrder.getShippingAddress().getStateName())) {
                 FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address State", "can only contain alphabetical characters."));
                 valid = false;
             }

             //Country: Alphabetic, Required
             if (!isNotEmpty(newDeliveryOrder.getShippingAddress().getCountry())) {
                 FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address Country", "cannot be empty."));
                 valid = false;
             }
             if (!isAlphabetic(newDeliveryOrder.getShippingAddress().getCountry())) {
                 FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address Country", "can only contain alphabetical characters."));
                 valid = false;
             }
             }
         }
        else if (purchaseOrder.getDeliveryOrders().size() == 2){
            if (!isNotEmpty(newDeliveryOrder.getShippingAddress().getAddressLine1())) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address Line 1", "cannot be empty."));
                valid = false;
            }
            if (!isAlphanumeric(newDeliveryOrder.getShippingAddress().getAddressLine1())) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address Line 1", "can only contain alphanumeric characters."));
                valid = false;
            }

            // Zipcode: Numeric, Required
            if (!isNotEmpty(newDeliveryOrder.getShippingAddress().getZipCode())) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address Zip Code", "cannot be empty."));
                valid = false;
            }
            if (!isNumeric(newDeliveryOrder.getShippingAddress().getZipCode())) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address Zip Code", "can only contain numeric characters."));
                valid = false;
            }

            // City: Alphabetic, Required
            if (!isNotEmpty(newDeliveryOrder.getShippingAddress().getCity())) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address City", "cannot be empty."));
                valid = false;
            }
            if (!isAlphabetic(newDeliveryOrder.getShippingAddress().getCity())) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address City", "can only contain alphabetical characters."));
                valid = false;
            }

            // State: Alphabetic, Required
            if (!isNotEmpty(newDeliveryOrder.getShippingAddress().getStateName())) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address State", "cannot be empty."));
                valid = false;
            }
            if (!isAlphabetic(newDeliveryOrder.getShippingAddress().getStateName())) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address State", "can only contain alphabetical characters."));
                valid = false;
            }

            //Country: Alphabetic, Required
            if (!isNotEmpty(newDeliveryOrder.getShippingAddress().getCountry())) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address Country", "cannot be empty."));
                valid = false;
            }
            if (!isAlphabetic(newDeliveryOrder.getShippingAddress().getCountry())) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address Country", "can only contain alphabetical characters."));
                valid = false;
            }
            
            if (!isNotEmpty(newDeliveryOrder2.getShippingAddress().getAddressLine1())) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address Line 1", "cannot be empty."));
                valid = false;
            }
            if (!isAlphanumeric(newDeliveryOrder2.getShippingAddress().getAddressLine1())) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address Line 1", "can only contain alphanumeric characters."));
                valid = false;
            }

            // Zipcode: Numeric, Required
            if (!isNotEmpty(newDeliveryOrder2.getShippingAddress().getZipCode())) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address Zip Code", "cannot be empty."));
                valid = false;
            }
            if (!isNumeric(newDeliveryOrder2.getShippingAddress().getZipCode())) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address Zip Code", "can only contain numeric characters."));
                valid = false;
            }

            // City: Alphabetic, Required
            if (!isNotEmpty(newDeliveryOrder2.getShippingAddress().getCity())) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address City", "cannot be empty."));
                valid = false;
            }
            if (!isAlphabetic(newDeliveryOrder2.getShippingAddress().getCity())) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address City", "can only contain alphabetical characters."));
                valid = false;
            }

            // State: Alphabetic, Required
            if (!isNotEmpty(newDeliveryOrder2.getShippingAddress().getStateName())) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address State", "cannot be empty."));
                valid = false;
            }
            if (!isAlphabetic(newDeliveryOrder2.getShippingAddress().getStateName())) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address State", "can only contain alphabetical characters."));
                valid = false;
            }

            //Country: Alphabetic, Required
            if (!isNotEmpty(newDeliveryOrder2.getShippingAddress().getCountry())) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address Country", "cannot be empty."));
                valid = false;
            }
            if (!isAlphabetic(newDeliveryOrder2.getShippingAddress().getCountry())) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Shipping Address Country", "can only contain alphabetical characters."));
                valid = false;
            }
        }

        return valid;
    }

    private boolean isAlphabetic(String str) {
        if (str.matches("[a-zA-Z\\s]*")) {
            return true;
        } else {
            return false;
        }
    }

    private boolean isAlphanumeric(String str) {

        if (str.matches("[a-zA-z0-9\\s]*")) {
            return true;
        } else {
            return false;
        }

    }

    private boolean isNumeric(String str) {
        if (str.matches("[0-9]*")) {
            return true;
        } else {
            return false;
        }

    }

    private boolean isNotEmpty(String str) {
        if (str == null) {
            return false;
        }
        if (str.equals("")) {
            return false;
        }
        return true;
    }

}
